import os
import re
import yaml
import sys
from pathlib import Path
from core import RequestExecutor
import argparse
from jinja2 import Environment, FileSystemLoader
import smtplib
from email.mime.text import MIMEText
from PrintToConsole import print_colored_results

#  确保其他目录的包能导入
# 获取当前脚本的父目录（apiselfexe），再获取父目录
project_root = Path(__file__).parent.parent
sys.path.append(str(project_root))

from handle.handle_path import API_CASE_FOR_YAML_DIR
from handle.handle_yaml import api_yaml_handle



def load_tests(directory):
    """加载YAML测试用例
    Args:
        directory: 测试用例目录
    Returns:
        测试用例列表
    """
    tests = []
    for file in os.listdir(directory):
        if file.endswith(".yaml"):
            with open(os.path.join(directory, file), encoding="utf-8") as f:
                tests.extend(yaml.safe_load(f))
    return tests

def find_key_in_dict(dic, key):
    """
    查找多层嵌套字典键的值
    :param dic:
    :param key:
    :return:
    """
    if key in dic:
        return dic[key]
    for k, v in dic.items():
        if isinstance(v, dict):
            result = find_key_in_dict(v, key)
            if result is not None:
                return result
    return None

def file_sort(dirPath):
    """
    将获取的文件列表生成一个以文件的数字为键的字典
    :return:
    """
    dic = {}
    for i in os.listdir(dirPath):
        string = i.split(".")[0]
        num = re.findall(r'\d+', string)[0]
        dic[f"{num}"] = i
    return dic

def generate_report(results, template_path="templates"):
    """生成HTML报告
    Args:
        results: 测试结果列表
        template_path: 模板目录
    """
    env = Environment(loader=FileSystemLoader(template_path))
    template = env.get_template("report_template.html")
    with open("test_report.html", "w") as f:
        f.write(template.render(results=results))


def send_alert(email_config):
    """发送告警邮件
    Args:
        email_config: 邮件配置字典
    """
    msg = MIMEText("接口测试发现失败用例，请及时查看！")
    msg["Subject"] = "接口测试告警"
    msg["From"] = email_config["sender"]
    msg["To"] = email_config["receiver"]

    with smtplib.SMTP(email_config["smtp_server"], email_config["port"]) as server:
        server.starttls()
        server.login(email_config["sender"], email_config["password"])
        server.sendmail(email_config["sender"], email_config["receiver"], msg.as_string())




def run_thread(dirPath):
    """主入口函数"""
    # 解析命令行参数
    parser = argparse.ArgumentParser()
    parser.add_argument("--console", action="store_true", help="控制台输出结果")
    parser.add_argument("--html", action="store_true", help="生成HTML报告")
    parser.add_argument("--email", action="store_true", help="发送邮件通知")
    args = parser.parse_args()

    # 配置信息
    config = {
        "base_url": "http://api.example.com",
        "email": {
            "sender": "your_email@example.com",
            "password": "your_password",
            "receiver": "receiver@example.com",
            "smtp_server": "smtp.example.com",
            "port": 587
        }
    }

    # 执行测试
    executor = RequestExecutor({})

    cases = file_sort(dirPath)
    for case_key in sorted(cases, key=lambda x: int(x)):
        yaml_data = api_yaml_handle(cases[case_key])
        dic = dict()
        dic["name"] = find_key_in_dict(yaml_data, "name")
        dic["url"] = find_key_in_dict(yaml_data, "url")
        dic["method"] = find_key_in_dict(yaml_data, "method")
        dic["headers"] = find_key_in_dict(yaml_data, "header")
        dic["data"] = find_key_in_dict(yaml_data, "data")
        dic["extract"] = find_key_in_dict(yaml_data, "extract")
        dic["assertions"] = find_key_in_dict(yaml_data, "assertions")
        executor.execute_request(dic)





    # # 结果处理
    if args.console:
        print_colored_results(executor.results)

    if args.html:
        generate_report(executor.results)
        print("HTML报告已生成: test_report.html")

    if args.email and any(not r["success"] for r in executor.results):
        send_alert(config["email"])
        print("已发送告警邮件")


run_thread(API_CASE_FOR_YAML_DIR)